#define TMIN 0.1
#define TMAX 20.
#define PRECISION 0.001
#define RAYMATCH_TIME 128
#define AA 3
vec2 fixUV(in vec2 c) {
    return (2. * c - iResolution.xy) / min(iResolution.x, iResolution.y);
}

float sdfShpere(in vec3 p) {
    return length(p - vec3(0., 0., 2.)) - 1.5;
}

float rayMatch(in vec3 ro, in vec3 rd) {
    float t = TMIN;

    for(int i = 0; i < RAYMATCH_TIME && t < TMAX; i++) {
        vec3 p = ro + t * rd;
        float d = sdfShpere(p);
        if(d < PRECISION)
            break;
        t += d;
    }

    return t;
}

// 计算法线
vec3 calcNormal(in vec3 p) {
    const float h = 0.0001;
    const vec2 k = vec2(1, -1);
    return normalize(k.xyy * sdfShpere(p + k.xyy * h) +
        k.yyx * sdfShpere(p + k.yyx * h) +
        k.yxy * sdfShpere(p + k.yxy * h) +
        k.xxx * sdfShpere(p + k.xxx * h));
}

vec3 render(in vec2 p) {
    vec3 col;
    vec3 ro = vec3(0., 0., -1.5);
    vec3 rd = normalize(vec3(p, 0.) - ro);
    float t = rayMatch(ro, rd);

    if(t < TMAX) {
        vec3 pos = ro + t * rd;
        vec3 normal = calcNormal(pos);
        float z = 2.+sin(iTime)*2.;
        // 光照位置
        vec3 light =vec3(z,2.,z);
        // 漫反射角度
        float dif =clamp( dot(normalize(light-pos),normal),0.,1.);
        // 环境光角度
        float amb =0.5+0.5*dot(normal,vec3(0.,1.,0.));
        col =amb*vec3(0.23,0.23,0.23)+dif* vec3(1.);
    }

    return sqrt(col);
}

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec3 color = vec3(0.);
    for(int i =0;i<AA;i++){
        for(int j =0;j<AA;j++){
            vec2 offset=2.*(vec2(float(i),float(j))/float(AA)-0.5);
            vec2 uv = fixUV(fragCoord+offset);
            color +=render(uv);
        }
    }
  
    fragColor = vec4( color /=float(AA*AA), 1.);
}